package server.socket;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;

import date.util.FormatDate;
import javafx.beans.property.SimpleStringProperty;

public class Server {

	private final int PORT = 8888;//端口

	//消息类型标志
	private final String LOGIN = "Login";
	private final String LOGOUT = "Logout";
	private final String TALK = "Talk";
	private final String UP = "Up";
	private final String DOWN = "Down";
	private final String SERVERCLOSE = "ServerClose";

	private ServerSocket server;//服务器socket
	private HashMap<String, SocketHandler> clientMap;//客户map
	private ArrayList<String> userList = new ArrayList<>();//客户列表

	private SimpleStringProperty receMsg = new SimpleStringProperty();//接收消息字符串

	public Server(SimpleStringProperty receMsg) {
		this.clientMap = new HashMap<>();
		this.receMsg = receMsg;
	}

	/**
	 * 开始接听
	 */
	public void startListen() {
		try {
			server = new ServerSocket(this.PORT);
			receMsg.set(FormatDate.getDate()+"\n"+"开始监听......" + "\r\n");
			while (true) {
				Socket client = server.accept();
				SocketHandler socketHandler = new SocketHandler(client);
				socketHandler.start();

			}
		} catch (IOException e) {
			// e.printStackTrace();
		}

	}

	/**
	 * 停止监听
	 */
	public void stopListen() {
		receMsg.set(FormatDate.getDate()+"\n"+"停止监听......" + "\r\n");
		if (clientMap.size() != 0) {
			while (userList.size() != 0) {
				SocketHandler socketHandler = clientMap.get(userList.get(0));
				socketHandler.sendMessage(SERVERCLOSE);
				socketHandler.close();
			}
		}
		try {
			server.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * socket处理线程
	 * @author huangyk
	 *
	 */
	class SocketHandler extends Thread {
		private Socket socket;
		private BufferedReader reader;
		private BufferedWriter writer;
		private String user;
		private String ipPort;

		public SocketHandler(Socket socket) {
			this.socket = socket;
			try {
				this.reader = new BufferedReader(new InputStreamReader(this.socket.getInputStream()));
				this.writer = new BufferedWriter(new OutputStreamWriter(this.socket.getOutputStream()));
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

		@Override
		public void run() {
			try {
				while (true) {
					String msg = reader.readLine();
					if (msg != null) {
						synchronized (receMsg) {
							receMsg.set(FormatDate.getDate() + "\n" + msg + "\r\n");
						}
						if (handleMessage(msg)) {
							break;
						}
					}
				}
			} catch (IOException e) {
				// close();
				// 客户端主动断开
				// e.printStackTrace();
			}

		}

		/**
		 * 消息处理
		 * @param msg
		 * @return
		 */
		public boolean handleMessage(String msg) {
			String[] str = msg.split(",");
			boolean flag = false;
			switch (str[0]) {
			case LOGIN:
				user = str[1] + "-" + str[2];
				ipPort = str[2];
				broadcast(LOGIN);
				sendToUser();
				clientMap.put(user, this);
				userList.add(user);
				flag = false;
				break;
			case LOGOUT:
				close();
				broadcast(LOGOUT);
				flag = true;
				break;
			case TALK:
				break;
			default:
				break;

			}
			return flag;
		}

		/**
		 * 向客户发送消息
		 * @param msg
		 */
		public void sendMessage(String msg) {
			try {
				this.writer.write(msg);
				this.writer.newLine();
				this.writer.flush();
			} catch (IOException e) {
				e.printStackTrace();
			}

		}
		/**
		 * 关闭与客户端的连接
		 */
		public void close() {
			try {
				clientMap.remove(user);
				userList.remove(user);
				this.reader.close();
				this.writer.close();
				this.socket.close();
			} catch (IOException e) {
				e.printStackTrace();
			}

		}
		/**
		 * 向其他所有在线用户广播消息
		 * @param str
		 */
		public void broadcast(String str) {
			if (clientMap.size() != 0) {
				Iterator<String> userList = clientMap.keySet().iterator();
				String msg = str.equals(LOGIN) ? UP + "," + user.substring(0, user.indexOf("-")) + "," + ipPort
						: DOWN + "," + user.substring(0, user.indexOf("-")) + "," + ipPort;
				while (userList.hasNext()) {
					clientMap.get(userList.next()).sendMessage(msg);

				}
			}

		}
		/**
		 * 告知客户端当前在线用户的信息
		 */
		public void sendToUser() {
			if (clientMap.size() != 0) {
				Iterator<String> userList = clientMap.keySet().iterator();
				while (userList.hasNext()) {
					String user = userList.next();
					String msg = UP + "," + user.substring(0, user.indexOf("-")) + ","
							+ user.substring(user.indexOf("-") + 1);
					sendMessage(msg);
				}
			}
		}

	}

}
